#ifndef _ACCURATE_TWO_WAY_COUPLER_H
#define _ACCURATE_TWO_WAY_COUPLER_H


#ifndef _WIN32_WINNT		// Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0601		// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif	

#include "stdafx.h"
#include "FluidSparseMatrix.h"
#include "CSRMatrix.h"
#include "MatrixSolver.h"


class GridField;
class TwowayCoupler;





class TwowayCoupler
{
	friend class ParallelMatrixFormer;
public:
	TwowayCoupler();
	TwowayCoupler(GridField* grid);
	virtual ~TwowayCoupler();
	void SetFluidGrid(GridField* grid);
	void Projection(double timeStep, double rho, bool needFormMatrix = true);
	CSRMatrix* GetCSRMatrix();
	FLuidSparseMatrix* GetFluidMatrix();
	void FormMatrix(double timeStep, double rho);
	void FormDivergence(double timeStep, double rho);
protected:
	void formMatrixAndDivergence(double timeStep, double rho);
	void solveForPressure();
	void projectVelocity(double timeStep, double rho);
	void calculateDGForCell(int i, int j, int k, double timeStep, double rho, FluidSparseVector& result);
	double calculateDIntermediateStepForCell(int i, int j, int k, double timeStep, double rho);
	void getAccAtUFace(int i, int j, int k, double rho, FluidSparseVector& ret, bool neg = false);
	void getAccAtVFace(int i, int j, int k, double rho, FluidSparseVector& ret, bool neg = false);
	void getAccAtWFace(int i, int j, int k, double rho, FluidSparseVector& ret, bool neg = false);
	void invalidAccCache();
	std::vector<FluidSparseVector> mUAccCache;
	std::vector<FluidSparseVector> mVAccCache;
	std::vector<FluidSparseVector> mWAccCache;
	int*** mUAccCacheIdx;
	int*** mVAccCacheIdx;
	int*** mWAccCacheIdx;
	GridField* mFluidGrid;
	FLuidSparseMatrix mMatrix;
	CSRMatrix mCSRMatrix;
	MatrixSolver* mSolver;
	std::vector<double> mCompactRHS;
	bool*** mbUpdateU;
	bool*** mbUpdateV;
	bool*** mbUpdateW;
	//double*** mRHS;
	int mNumX;
	int mNumY;
	int mNumZ;
	int mDim;
	static tbb::mutex msMutex;
};

#endif